﻿using FluentModbus;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;

namespace PeAutoControl
{
    internal static class Modbus
    {
        /// <summary>
        /// 日志记录器
        /// </summary>
        private static ILogger _logger;

        /// <summary>
        /// Modbus服务
        /// </summary>
        private static ModbusTcpServer? _modbusServer;

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="logger"></param>
        internal static void Start(ILogger logger, Action<string> dataCallback = default)
        {
            if (_modbusServer is not null)
            {
                _logger.LogError("服务已经启动，如需重启请先停止！");
                return;
            }
            _logger = logger;

            _modbusServer = new ModbusTcpServer(_logger)
            {
                EnableRaisingEvents = true,
            };

            _modbusServer.RegistersChanged += (sender, registerAddresses) =>
            {
                Task.Run(() =>
                {
                    // 修改过的寄存器
                    var shorts = _modbusServer.GetHoldingRegisterBuffer<short>(0x00).ToArray();
                    string str = new(Array.ConvertAll(shorts.ToList().Skip(10).Take(40).ToArray(), x => (char)x));
                    str = str.TrimEnd('\0');

                    if (!string.IsNullOrWhiteSpace(str))
                    {
                        _logger.LogInformation($"收到数据：{str}");
                        SendData(str);
                    }
                });
            };

            _modbusServer.Start(new IPEndPoint(IPAddress.Any, config.port));
            _logger.LogInformation($"服务已启动，端口：{config.port}");
        }

        /// <summary>
        /// 关闭服务
        /// </summary>
        internal static void Dispose()
        {
            _modbusServer?.Dispose();
            _modbusServer = null;
        }

        internal static void SendData(string value)
        {
            if (_modbusServer is not null)
            {
                var registers = _modbusServer.GetHoldingRegisters();
                //registers.SetLittleEndian<int>(address: 0, 10);

                // 将字符串转换为字节数组
                byte[] bytes = Encoding.UTF8.GetBytes(value);

                // 要写入的起始寄存器地址
                int startAddress = 50;

                // 按照每个字节写入一个寄存器的方式，将字符串写入到连续的保持寄存器中
                for (int i = 0; i < bytes.Length; i++)
                {
                    registers.SetLittleEndian<byte>(address: startAddress + i, bytes[i]);
                }
            }
        }
    }
}